package cn.easyplatform.studio.web.views.impl;

import cn.easyplatform.entities.beans.project.ProjectBean;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.entity.QueryModelCmd;
import cn.easyplatform.studio.cmd.entity.QueryTableCmd;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.vos.EntityVo;
import cn.easyplatform.studio.vos.TableVo;
import cn.easyplatform.studio.web.editors.EditorCallback;
import cn.easyplatform.type.EntityType;
import org.apache.commons.lang3.StringUtils;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zul.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DbExportView extends AbstractView<List<EntityVo>> {
    private Vlayout vlayout;
    private Bandbox searchbox;
    private Listbox sourcesBox;
    private Listbox targetsBox;
    private List<TableVo> allData;
    private Map<EntityVo, List<EntityVo>> data;
    /**
     * @param cb
     */
    protected DbExportView(EditorCallback<List<EntityVo>> cb, Component component) {
        super(component, cb);
    }

    @Override
    protected void createContent(Component parent) {

        vlayout = new Vlayout();
        vlayout.setVflex("1");

        Hlayout topHlayout = new Hlayout();
        topHlayout.setHflex("1");

        Image image = new Image();
        image.setSrc("~./images/db.gif");
        image.setStyle("margin-top:3px");
        image.setParent(topHlayout);
        Div div = new Div();
        div.setStyle("margin-top:3px");
        div.setParent(topHlayout);
        Label label1 = new Label(Labels.getLabel("editor.db.list"));
        label1.setParent(div);

        searchbox = new Bandbox();
        searchbox.setId("dbExportView_bandbox_search");
        searchbox.setPlaceholder(Labels.getLabel("navi.search.placeholder"));
        searchbox.addEventListener(Events.ON_OK, this);
        searchbox.addEventListener(Events.ON_CHANGE, this);
        searchbox.addEventListener(Events.ON_OPEN, this);
        searchbox.setParent(topHlayout);
        searchbox.addEventListener(Events.ON_OK, this);
        searchbox.addEventListener(Events.ON_OPEN, this);

        topHlayout.setParent(vlayout);

        Hlayout centerHlayout = new Hlayout();
        centerHlayout.setHflex("1");
        centerHlayout.setVflex("1");
        centerHlayout.setStyle("padding-top:3px");

        sourcesBox = new Listbox();
        sourcesBox.setId("dbExportView_listbox_sources");
        sourcesBox.setHflex("1");
        sourcesBox.setVflex("1");
        sourcesBox.setCheckmark(true);
        sourcesBox.setMultiple(true);
        sourcesBox.setMold("paging");
        sourcesBox.setPageSize(20);
        sourcesBox.setParent(centerHlayout);

        Listhead listhead = new Listhead();
        listhead.setSizable(true);
        listhead.setParent(sourcesBox);

        Listheader idListheader = new Listheader();
        idListheader.setLabel(Labels.getLabel("entity.name"));
        idListheader.setWidth("200px");
        idListheader.setParent(listhead);

        Listheader nameListheader = new Listheader();
        nameListheader.setLabel(Labels.getLabel("entity.desp"));
        nameListheader.setWidth("200px");
        nameListheader.setParent(listhead);

        Vlayout middleLayout = new Vlayout();
        middleLayout.setSpacing("10px");
        middleLayout.setWidth("24px");
        middleLayout.setParent(centerHlayout);

        Image createAllImg = new Image();
        createAllImg.setId("dbExportView_image_createAll");
        createAllImg.setSrc("~./images/rightrightarrow_g.png");
        createAllImg.setStyle("cursor:pointer");
        createAllImg.setTooltip(Labels.getLabel("button.createAll"));
        createAllImg.setParent(middleLayout);
        createAllImg.addEventListener(Events.ON_CLICK, this);

        Image createImg = new Image();
        createImg.setId("dbExportView_image_create");
        createImg.setSrc("~./images/rightarrow_g.png");
        createImg.setStyle("cursor:pointer");
        createImg.setTooltip(Labels.getLabel("button.create"));
        createImg.setParent(middleLayout);
        createImg.addEventListener(Events.ON_CLICK, this);

        Image removeImg = new Image();
        removeImg.setId("dbExportView_image_remove");
        removeImg.setSrc("~./images/leftarrow_g.png");
        removeImg.setStyle("cursor:pointer");
        removeImg.setTooltip(Labels.getLabel("button.remove"));
        removeImg.setParent(middleLayout);
        removeImg.addEventListener(Events.ON_CLICK, this);

        Image removeAllImg = new Image();
        removeAllImg.setId("dbExportView_image_removeAll");
        removeAllImg.setSrc("~./images/leftleftarrow_g.png");
        removeAllImg.setStyle("cursor:pointer");
        removeAllImg.setTooltip(Labels.getLabel("button.removeAll"));
        removeAllImg.setParent(middleLayout);
        removeAllImg.addEventListener(Events.ON_CLICK, this);

        middleLayout.setParent(centerHlayout);

        targetsBox = new Listbox();
        targetsBox.setId("dbExportView_listbox_targets");
        targetsBox.setHflex("1");
        targetsBox.setVflex("1");
        targetsBox.setCheckmark(true);
        targetsBox.setMultiple(true);
        targetsBox.setMold("paging");
        targetsBox.setPageSize(20);
        targetsBox.setParent(centerHlayout);
        Listhead newListhead = (Listhead) listhead.clone();
        newListhead.setParent(targetsBox);

        centerHlayout.setParent(vlayout);
        vlayout.setParent(parent);

        Hlayout bottomHlayout = new Hlayout();
        bottomHlayout.setHflex("1");
        bottomHlayout.setHeight("38px");
        bottomHlayout.setParent(vlayout);
        Div d = new Div();
        d.setHflex("1");
        bottomHlayout.appendChild(d);

        Button btn = new Button(Labels.getLabel("button.ok"));
        btn.setId("dbExportView_image_chooseBtn");
        btn.setStyle("margin-top: 8px;");
        btn.setSclass("pull-right");
        btn.setIconSclass("z-icon-check");
        btn.addEventListener(Events.ON_CLICK, this);
        btn.setParent(bottomHlayout);

        data = new HashMap<EntityVo, List<EntityVo>>();
        redraw();
    }

    private void redraw() {
        List<EntityVo> ds = StudioApp.execute(new QueryModelCmd(
                EntityType.DATASOURCE.getName()));
        ProjectBean pb = Contexts.getProject();
        EntityVo master = null;
        for (EntityVo vo : ds) {
            if (pb.getBizDb().equals(vo.getId())) {
                master = vo;
                break;
            }
        }
        ds.remove(master);
        Listgroup group = createDb(master);
        List<EntityVo> result = StudioApp.execute(new QueryTableCmd(master
                .getId()));
        createTables(group, result);
        data.put(master, result);

        for (EntityVo vo : ds) {
            group = createDb(vo);
            group.setOpen(false);
            group.addEventListener(Events.ON_OPEN, this);
        }
    }

    private void createTables(Listgroup group, List<EntityVo> data) {
        List<Listitem> items = sourcesBox.getItems();
        int pos = items.indexOf(group);
        for (int i = 0; i < data.size(); i++) {
            EntityVo tv = data.get(i);
            Listitem ti = new Listitem();
            ti.appendChild(new Listcell(tv.getId()));
            ti.appendChild(new Listcell(tv.getName()));
            ti.setDraggable("table");
            ti.setValue(tv);
            ti.addEventListener(Events.ON_DOUBLE_CLICK, this);
            items.add(pos + i + 1, ti);
        }
    }

    private Listgroup createDb(EntityVo ds) {
        Listgroup group = new Listgroup();
        group.appendChild(new Listcell(ds.getId()));
        group.appendChild(new Listcell(ds.getName()));
        group.setValue(ds);
        sourcesBox.appendChild(group);
        return group;
    }

    @Override
    public void onEvent(Event event) throws Exception {
        Component c = event.getTarget();
        if (c instanceof Bandbox) {
            Bandbox search = (Bandbox) c;
            String val = null;
            if (event instanceof OpenEvent) {
                OpenEvent evt = (OpenEvent) event;
                val = (String) evt.getValue();
            } else
                val = search.getValue();
            search(val);
        }

        if (event.getTarget().getId().equals("dbExportView_image_createAll"))
            select(false);
        else if (event.getTarget().getId().equals("dbExportView_image_create"))
            select(true);
        else if (event.getTarget().getId().equals("dbExportView_image_remove"))
            unselect(true);
        else if (event.getTarget().getId().equals("dbExportView_image_removeAll"))
            unselect(false);
        else if (event.getTarget().getId().equals("dbExportView_image_chooseBtn"))
            choose();
    }

    private void select(boolean selectFlag) {
        for (Listitem sel : sourcesBox.getItems()) {
            if (selectFlag && !sel.isSelected())
                continue;
            if (sel.getValue() != null) {
                boolean exists = false;
                EntityVo s = sel.getValue();
                for (Listitem li : targetsBox.getItems()) {
                    EntityVo t = li.getValue();
                    if (s.getId().equals(t.getId())) {
                        exists = true;
                        break;
                    }
                }
                if (!exists) {
                    Listitem li = new Listitem();
                    li.appendChild(new Listcell(s.getId()));
                    li.appendChild(new Listcell(s.getName()));
                    li.setValue(s);
                    targetsBox.appendChild(li);
                }
            }
        }
    }

    private void unselect(boolean selectedFlag) {
        if (selectedFlag) {
            if (targetsBox.getSelectedCount() > 0) {
                List<Listitem> items = new ArrayList<Listitem>();
                for (Listitem li : targetsBox.getSelectedItems())
                    items.add(li);
                for (Listitem li : items)
                    li.detach();
            }
        } else
            targetsBox.getItems().clear();
    }

    private void choose() {
        List<EntityVo> dicVos = new ArrayList<>();
        if (targetsBox.getItems() != null && targetsBox.getItems().size() > 0) {
            for (Listitem li : targetsBox.getItems()) {
                EntityVo e = li.getValue();
                dicVos.add(e);
            }
        }
        if (cb != null)
            cb.setValue(dicVos);
        vlayout.getRoot().detach();
        onCloseClick(win);
    }

    private void search(String val) {
        if (Strings.isBlank(val)) {
            for (Listgroup group : sourcesBox.getGroups()) {
                List<EntityVo> cv = data.get(group.getValue());
                if (cv != null) {
                    sourcesBox.getItems().removeAll(group.getItems());
                    createTables(group, cv);
                }
            }
        } else {
            for (Listgroup group : sourcesBox.getGroups()) {
                List<EntityVo> cv = data.get(group.getValue());
                if (cv != null) {
                    sourcesBox.getItems().removeAll(group.getItems());
                    List<EntityVo> cp = new ArrayList<EntityVo>();
                    for (EntityVo tv : cv) {
                        if (StringUtils.indexOfIgnoreCase(tv.getId(), val) >= 0
                                || StringUtils.indexOfIgnoreCase(tv.getName(),
                                val) >= 0) {
                            cp.add(tv);
                        }
                    }
                    createTables(group, cp);
                }
            }
        }
    }
}
